package com.kalaqia.permission.aspect;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * Created by ccj on 2016/9/2.
 */

@Aspect
public class PermissionEvent {

    public static final int REQUEST_CODE_ASK_PERMISSIONS = 123;
    private static final String TAG = PermissionEvent.class.getSimpleName();

    @Pointcut("execution(@NeedPermission public * *..*.*(..)) && @annotation(name)")
    public void needPermissionAspect(NeedPermission name) {

    }

    @Pointcut("execution(* onRequestPermissionsResult**(..))")
    public void resultPermissionAspect() {

    }

    @Around("resultPermissionAspect()")
    public void resultPermissionAspectEvent(ProceedingJoinPoint joinPoint) throws Throwable {
        final Context context = (Context) joinPoint.getTarget();
        if (isCallBack && !PermissionsChecker.getInstance(context).isHasAllPermissions(needvalue)) {
            if (context instanceof Activity) {
                AlertDialog.Builder builder = new AlertDialog.Builder(context);
                builder.setCancelable(false);
                builder.setTitle(context.getString(R.string.app_name));
                builder.setNegativeButton("设置", (dialog, which) -> {
                    try {
                        context.startActivity(PermissionSettingsUtils.getInstance().getPermissionSettingIntent());
                    } catch (Exception e) {
                        context.startActivity(PermissionSettingsUtils.getInstance().getNormalPermissionIntent());
                    }
                });
                builder.setMessage(message).setPositiveButton("确认", (dialog, which) -> {
                }).create().show();
            }
        } else {
            this.joinPoint.proceed();
        }
    }


    private String[] needvalue;
    private String message;
    private boolean isCallBack = true;
    private ProceedingJoinPoint joinPoint;

    @Around("needPermissionAspect(NeedPermission)")
    public void needPermissionAspectEvent(ProceedingJoinPoint joinPoint) throws Throwable {
        Log.i(TAG, "cut_event");
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        NeedPermission needPermission = methodSignature.getMethod().getAnnotation(NeedPermission.class);
        String[] value = needPermission.value();
        message = needPermission.getmsg();
        isCallBack = needPermission.isCallBack();
        for (String aValue : value) {
            Log.i(TAG, "value=" + aValue);
        }
        ArrayList<String> strings = new ArrayList<>();
        ArrayList<String> stringsMsg = new ArrayList<>();
        Context context = (Context) joinPoint.getTarget();

        //判断是否有权限没有申请通过
        boolean flag = false;
        //检查权限是否存在
        for (String permission : value) {
//            String op = AppOpsManagerCompat.permissionToOp(permission);
//            if (TextUtils.isEmpty(op)) continue;
//            int result = AppOpsManagerCompat.noteProxyOp(context, op, context.getPackageName());
//            if (result == AppOpsManagerCompat.MODE_IGNORED){
//                //权限不被允许
//                flag = true;
//                stringsMsg.add(setCallPermissionMsg(context, permission));
//                strings.add(permission);
//                Log.i(TAG, "needed value=" + permission);
//            }else{
//                result = ContextCompat.checkSelfPermission(context, permission);
//                if (result != PackageManager.PERMISSION_GRANTED){
//                    flag = true;
//                    stringsMsg.add(setCallPermissionMsg(context, permission));
//                    strings.add(permission);
//                    Log.i(TAG, "needed value=" + permission);
//                }
//            }
            if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                flag = true;
                stringsMsg.add(setCallPermissionMsg(context, permission));
                strings.add(permission);
                Log.i(TAG, "needed value=" + permission);
//                break;
            }
        }

        if (!flag) {
            joinPoint.proceed();
        } else {
            this.joinPoint = joinPoint;
            String[] values = new String[strings.size()];
            strings.toArray(values);
//            needvalue = values;
            needvalue = value;
            Log.i(TAG, "strings=" + strings.toString() + ",values=" + values);
            callRequestPermission(context, stringsMsg.toString(), values);
        }
    }


    /**
     * @param context     上下文
     * @param message     请求权限的信息,
     * @param permissions 所需的权限
     */
    private void callRequestPermission(final Context context, String message, final String[] permissions) {
        Class<?> clzz = context.getClass();
        Method[] methods = clzz.getDeclaredMethods();
        Method requestMethod = null;
        if (!(context instanceof ActivityCompat.OnRequestPermissionsResultCallback)) {
            throw new RuntimeException("申请权限的Activity未实现OnRequestPermissionsResultCallback接口");
        }
        for (Method method : methods) {
            RequestPermission requestPermissions = method.getAnnotation(RequestPermission.class);
            if (requestPermissions != null) {
                requestMethod = method;
            }
        }
        if (requestMethod != null) {
            //调用activity中 使用注解RequestPermission的方法.
            requestMethod.setAccessible(true);
            try {
                Log.e(TAG, "invoke");
                requestMethod.invoke(context, message, permissions);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        ActivityCompat.requestPermissions((Activity) context, permissions, REQUEST_CODE_ASK_PERMISSIONS);
    }

    /**
     * 当前运行时权限转中文选择器
     * <p>
     * 可以在activity中设置setResetPermissionMsg(true),
     * 然后实现接口{@link },达到想要的文字样式
     * 可参考 getDefaultMsg 方法,进行实现
     */
    private String setCallPermissionMsg(Context mContext, String permission) throws Exception {
        String permissions = null;
//        if (resetPermissionMsg) {
//            if (mContext instanceof CallPermissionMsg) {
//                permissions = callPermissionMsg.callPermissionMsg(permission);
//            } else {
//                throw new Exception("请实现CallPermissionMsg接口中的方法");
//
//            }
//        } else {
        permissions = getDefaultMsg(permission);
//        }
        return permissions;
    }

    @After("execution(* android.support.v4.app.FragmentActivity.onRequestPermissionsResult(..))")
    public void afterPermissionRequestBack(JoinPoint joinPoint) {
        Object[] objects = joinPoint.getArgs();
        Object object = joinPoint.getTarget();
        if (objects.length >= 1 && objects[0] instanceof Integer && object != null && object instanceof FragmentActivity) {
            int requestCode = (int) objects[0];
            invokeMethod(((FragmentActivity) object), requestCode);
        }
    }

    @SuppressWarnings("Since15")
    private static void invokeMethod(@NonNull FragmentActivity activity, @NonNull Integer requestCode) {
        Class clazz = activity.getClass();
        for (Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(NeedPermission.class)) {
                NeedPermission ann = method.getAnnotation(NeedPermission.class);
//                if (ann.value() == requestCode) {
//                    if (method.getParameterTypes().length > 0) {
//                        throw new RuntimeException("Cannot execute non-void method " + method.getName());
//                    }
//                    try {
//                        if (!method.isAccessible()) {
//                            method.setAccessible(true);
//                        }
//                        method.invoke(iPresenter);
//                    } catch (IllegalAccessException e) {
////                        YLog.e(e);
//                    } catch (InvocationTargetException e) {
////                        YLog.e(e);
//                    }
//                }
            }
        }
    }


    /**
     * 默认的权限信息转换
     */
    @NonNull
    private String getDefaultMsg(String permission) {
        String permissions = null;
        switch (permission) {
            case Manifest.permission.READ_CONTACTS:
                permissions = "获取联系人权限";
                break;
            case Manifest.permission.RECORD_AUDIO:
                permissions = "录音权限";
                break;
            case Manifest.permission.CALL_PHONE:
                permissions = "打电话权限";
                break;
            case Manifest.permission.CAMERA:
                permissions = "打开相机权限";
                break;
            case Manifest.permission.ACCESS_COARSE_LOCATION:
                permissions = "获取定位权限";
                break;
            case Manifest.permission.READ_EXTERNAL_STORAGE:
                permissions = "读取存储权限";
                break;
            case Manifest.permission.READ_SMS:
                permissions = "读取短信权限";
                break;
//            case Manifest.permission.WRITE_EXTERNAL_STORAGE:
//                permissions = "修改内存权限";
//                break;
            default:
                permissions = "其他权限";
                break;
        }
        return permissions;
    }

}
